package com.touni.lambda;

import cn.hutool.captcha.generator.MathGenerator;

import java.util.*;
import java.util.function.Supplier;
import java.util.jar.JarEntry;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;

/**
 * @ClassName : DemoMain
 * @Description :
 * distinct  去重
 * reduce  规约
 * list.stream().reduce(0, (a, b) -> a + b)
 * 0作为流的初始值，将0与下一个元素 叠加   在与下一个元素叠加  一个一个进行叠加
 *
 * @Author : lwq
 * @Date: 2020-11-02 09:58
 */
public class DemoMain {
   static List<BaseModel> baseList;

    static {
        baseList = new ArrayList<BaseModel>();
        baseList.add(new BaseModel("刘华",26,"男"));
        baseList.add(new BaseModel("刘已",26,"女"));
        baseList.add(new BaseModel("是啥",56,"男"));
        baseList.add(new BaseModel("自行车",16,"女"));
        baseList.add(new BaseModel("秩序册",89,"男"));
        baseList.add(new BaseModel("儿女",42,"男"));
        baseList.add(new BaseModel("瞅瞅",19,"女"));
        baseList.add(new BaseModel("分隔",52,"男"));
        baseList.add(new BaseModel("四渡赤水",46,"女"));
        baseList.add(new BaseModel("撒旦法",41,"男"));
    }

    public static void main(String[] args) {
        //streamBase1();
        //streamBase2();
        //streamFlatMap();
        createStream();
    }

    public static void createStream(){
        //常用的创建流的形式    Stream.of   Arrays.stream    集合.stream
        /*Stream<Integer> integerStream = Stream.of(1, 2, 3, 4);
        int[] a = {1,3,4,5};
        IntStream intStream = Arrays.stream(a);
        Stream<Integer> boxed = intStream.boxed();
        Stream<BaseModel> stream = baseList.stream();*/
        // 无限流  自己生成流  Stream.generate 有供应源的  在并发环境下是不安全的
        //                    Stream.iterate
        // 生成的流是无穷无尽的
        /*Random random = new Random();
        Supplier<Integer> supplier = random::nextInt;
        Stream<Integer> generate = Stream.generate(supplier);
        generate.forEach(a -> System.out.println(a));
        Stream.iterate(0, a -> a + 2 ).forEach(b -> System.out.println(b));*/
        //斐波那契数列生成
        /*Stream.iterate(new int[]{0,1}, t -> new int[]{t[1],t[0] + t[1] }).limit(30).map(t -> t[0])
                .forEach(t -> System.out.println(t));*/
        DIYBaseSupplier supplier = new DIYBaseSupplier();
        //通过供应源来获取
        Stream.generate(supplier).limit(10).forEach(a -> System.out.println(a.intValue() + " "));
    }



    public static void streamBase2(){
        /*List<Integer> list = new ArrayList<>();
        list.add(12);
        list.add(526);
        list.add(30);
        list.add(96);
        // mapToInt  mapToDouble mapToLong 都会返回一个特殊的流  101
        int sum = list.stream().mapToInt(Integer::intValue).sum();
        IntStream intStream = list.stream().mapToInt(Integer::intValue);
        //特殊流 调用boxed()方法返回正常的流
        Stream<Integer> boxed = intStream.boxed();
        System.out.println(sum);*/
        /*OptionalInt max = baseList.stream().mapToInt(BaseModel::getAge).max();
        //如果没有最大值 显式指定一个默认值
        max.orElse(1);
        System.out.println(max.getAsInt());*/

        // range 不包含结束值  rangeClosed包含结束值   两者都包含起始值
        /*IntStream.range(1,3).forEach(a -> System.out.println(a));
        System.out.println("=============");
        IntStream.rangeClosed(1,3).forEach(b -> System.out.println(b));*/
        /*Stream.Builder<Object> builder = Stream.builder();
        builder.accept("sss");
        builder.accept("sss2");
        builder.add("2233");
        Stream<Object> build = builder.build();
        build.forEach(a -> System.out.println(a));*/
        //生成勾股数
        /*System.out.println("============生成勾股数1============");
        List<int[]> ggs = IntStream.rangeClosed(1, 100).boxed().
                flatMap(a -> IntStream.rangeClosed(a, 100).filter(b -> Math.sqrt(a * a + b * b) % 1 == 0)
                        .mapToObj(b -> new int[]{a, b, (int) Math.sqrt(a * a + b * b)})).collect(Collectors.toList());
        for (int[] ints : ggs){
            String str = "";
            for (int i : ints){
                str = str + i + " ";
            }
            System.out.println(str);
            System.out.println("============");
        }*/
        System.out.println("=========生成勾股数2=============");
        List<double[]> ggs2 = IntStream.rangeClosed(1, 100).boxed()
                .flatMap(a -> IntStream.rangeClosed(a, 100).mapToObj(b -> new double[]{a, b, Math.sqrt(a * a + b * b)})
                        .filter(t -> t[2] % 1 == 0)).collect(Collectors.toList());
        for (double[] d :ggs2){
            String str = "";
            for (double i : d){
                str = str + (int)i + "  ";
            }
            System.out.println(str);
            System.out.println("============");
        }



    }

    /**
     * flatMap：flatmap方法让你把一个流中的每个值都换成另一个流，然后把所有的流连接起来成为一个流。
     *   使流扁平化
     *
     */
    public static void streamFlatMap(){
        /*List<String> list = Arrays.asList("hello", "word");
        // Arrays.stream()将一个数组转换为一个流
        Stream<String[]> stream = list.stream().map(str -> str.split(""));
        Stream<String> stringStream = stream.flatMap(Arrays::stream);

        List<String> collect = list.stream().map(str -> str.split("")).
                flatMap(Arrays::stream).distinct().collect(Collectors.toList());
        for (String str : collect){
            System.out.println(str);
        }*/
        List<Integer> a = Arrays.asList(1, 2, 4, 5);
        List<Integer> b = Arrays.asList(2, 3, 4);
        List<int[]> collect = a.stream().flatMap(i -> b.stream().map(j -> new int[]{i, j})).collect(Collectors.toList());
        for (int[] ints : collect){
            System.out.println("=========");
            String str = "";
            for (int i :ints){
                str = str + i + " ";
            }
            System.out.println(str);
            System.out.println("=========");
        }
    }

    public static void streamBase1() {
        List<Integer> list = new ArrayList<>();
        list.add(12);
        list.add(17);
        list.add(29);
        list.add(29);
        list.add(526);
        list.add(526);
        list.add(30);
        list.add(96);
        /*System.out.println("=======开始求和========");
        Integer reduce = list.stream().reduce(0, (a, b) -> a + b);
        System.out.println(reduce);
        System.out.println("!!!!!!!!!!!!!!!!!!!!!!");
        Integer reduce1 = list.stream().reduce(0, Integer::sum);
        System.out.println(reduce1);
        System.out.println("！！！！！！！！！！！！！");
        Optional<Integer> reduce2 = list.stream().reduce((a, b) -> a + b);
        if (reduce2.isPresent()){
            System.out.println(reduce2.get());
        }*/
        /*System.out.println("=========求最大/最小的值============");
        Integer max1 = list.stream().reduce(0,(a,b) -> a > b ? a : b);
        System.out.println(max1);
        System.out.println("@@@@@@@@@@");
        Optional<Integer> max2 = list.stream().reduce(Integer::min);
        if (max2.isPresent()){
            System.out.println(max2.get()); 97
        }*/
        /*System.out.println("=========规约求list大小===========");
        Integer countByReduce = list.stream().map(all -> 1).reduce(0, (a, b) -> a + b);
        System.out.println(countByReduce);*/

        System.out.println("========distinct进行去重===========");
        System.out.println("size=" + list.size());
        list.stream().distinct().forEach(a -> System.out.println(a));
    }
}
